/*
 * A FilteredSet wraps a specified set object and applies a specified filter
 * to values passed to its add() method.  All of the other core set methods 
 * simply forward to the wrapped set instance.
 */
var FilteredSet = Set.extend(
    function FilteredSet(set, filter) {  // The constructor
        this.set = set;
        this.filter = filter;
    },
    {  // The instance methods
        add: function () {
            // If we have a filter, apply it
            if (this.filter) {
                for (var i = 0; i < arguments.length; i++) {
                    var v = arguments[i];
                    if (!this.filter(v))
                        throw new Error("FilteredSet: value " + v +
                            " rejected by filter");
                }
            }

            // Now forward the add() method to this.set.add()
            this.set.add.apply(this.set, arguments);
            return this;
        },
        // The rest of the methods just forward to this.set and do nothing else.
        remove: function () {
            this.set.remove.apply(this.set, arguments);
            return this;
        },
        contains: function (v) {
            return this.set.contains(v);
        },
        size: function () {
            return this.set.size();
        },
        foreach: function (f, c) {
            this.set.foreach(f, c);
        }
    });
